import 'dart:async';
import 'dart:io';
import 'dart:math';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:signage/app/modules/cast/controllers/cast_controller.dart';
import 'package:signage/app/modules/device/models/device_cached_info.dart';
import 'package:signage/app/modules/home/controllers/home_controller.dart';
import 'package:signage/app/utils/sp_util.dart';
import 'package:signage/l10n/l10n.dart';
import '../utils/toast_utils.dart';
import 'package:nfc_manager/nfc_manager.dart';

class BluetoothManager extends GetxService {
  BluetoothManager();

  static const platform = MethodChannel('com.signage.signage/l2cap');
  static const Duration CONNECT_TIMEOUT = Duration(seconds: 15);
  static const Duration OPERATION_TIMEOUT = Duration(seconds: 10);
  static const int MAX_RETRIES = 3;
  static const int MAX_CONCURRENT_CONNECTIONS = 6;

  // ESL Service UUID (Electronic Shelf Label Service)
  static const String ESL_SERVICE_UUID = "00001857-0000-1000-8000-00805F9B34FB";
  static const String DISPLAY_INFO_UUID =
      "00002BFA-0000-1000-8000-00805F9B34FB";
  static const String BATTERY_SERVICE_UUID =
      "0000180F-0000-1000-8000-00805F9B34FB";
  static const String BATTERY_LEVEL_UUID =
      "00002A19-0000-1000-8000-00805F9B34FB";
  static const String DEVICE_INFO_SERVICE_UUID =
      "0000180A-0000-1000-8000-00805F9B34FB";
  static const String FIRMWARE_VERSION_UUID =
      "00002A26-0000-1000-8000-00805F9B34FB";
  static const String BOARD_UUID = "00002A24-0000-1000-8000-00805F9B34FB";

  // L2CAP operations
  Future<void> createL2capChannel(BluetoothDevice device, int psm) async {
    try {
      await platform.invokeMethod('createL2capChannel', {
        'deviceId': device.remoteId.toString(),
        'psm': psm,
      });
    } catch (e) {
      print('L2CAP channel creation error: $e');
      rethrow;
    }
  }

  Future<void> closeL2capChannel(BluetoothDevice device) async {
    try {
      await platform.invokeMethod('closeL2capChannel', {
        'deviceId': device.remoteId.toString(),
      });
    } catch (e) {
      print('L2CAP channel close error: $e');
      rethrow;
    }
  }

  Future<Map<String, dynamic>> getL2capMtu(BluetoothDevice device) async {
    try {
      final result = await platform.invokeMethod('getL2capMtu', {
        'deviceId': device.remoteId.toString(),
      });
      return Map<String, dynamic>.from(result);
    } catch (e) {
      print('Error getting L2CAP MTU: $e');
      rethrow;
    }
  }

  Future<void> sendL2capData(BluetoothDevice device, Uint8List data) async {
    try {
      await platform.invokeMethod('sendL2capData', {
        'deviceId': device.remoteId.toString(),
        'data': data,
      });
    } catch (e) {
      print('L2CAP send error: $e');
      rethrow;
    }
  }

  // Command generation utilities
  Uint8List writeOLCP(int command, int objectId) {
    Uint8List data = Uint8List(7);
    data[0] = command;
    for (int i = 0; i < 6; i++) {
      data[i + 1] = (objectId >> (8 * i)) & 0xFF;
    }
    return data;
  }

  Uint8List writeOACP(int offset, int length, int mode) {
    Uint8List data = Uint8List(10);
    ByteData buffer = ByteData.view(data.buffer);

    buffer.setUint8(0, 0x06);
    buffer.setUint32(1, offset, Endian.little);
    buffer.setUint32(5, length, Endian.little);
    buffer.setUint8(9, mode);

    return data;
  }

  Uint8List executeDisplayControl(int screenNumber, int objectId) {
    Uint8List data = Uint8List(9);

    data[0] = 0x04;
    ByteData screenBytes = ByteData(2)
      ..setUint16(0, screenNumber, Endian.little);
    data.setRange(1, 3, screenBytes.buffer.asUint8List());

    ByteData objectIdData = ByteData(8)..setUint64(0, objectId, Endian.little);
    data.setRange(3, 9, objectIdData.buffer.asUint8List(0, 6));

    return data;
  }

  // Characteristic properties helper
  String getCharacteristicProperties(BluetoothCharacteristic c) {
    List<String> props = [];
    if (c.properties.read) props.add('读');
    if (c.properties.write) props.add('写');
    if (c.properties.writeWithoutResponse) props.add('无响应写');
    if (c.properties.notify) props.add('通知');
    if (c.properties.indicate) props.add('指示');
    if (c.properties.broadcast) props.add('广播');
    if (c.properties.authenticatedSignedWrites) props.add('认证签名写');
    if (c.properties.extendedProperties) props.add('扩展属性');
    if (c.properties.notifyEncryptionRequired) props.add('加密通知');
    if (c.properties.indicateEncryptionRequired) props.add('加密指示');
    return props.join(', ');
  }

  // Add these new properties
  final scanResults = <ScanResult>[].obs;
  final nfcScanResults = <DeviceCachedInfo>[].obs;
  final connectionProgress = <String, String>{}.obs; // 记录每个设备的连接状态
  final isConnecting = false.obs; // 批量连接进行中的标志
  final connectedDevices = <DeviceCachedInfo>[].obs;
  final connectionQueue = <BluetoothDevice>[].obs;

  // Add storage key constant
  static const String _storageKey = 'saved_devices';

  // 修改设备信息的缓存定义
  final deviceInfoMap = <String, DeviceCachedInfo>{}.obs;
  // Add method to initialize cached devices
  Future<void> initializeCachedDevices() async {
    try {
      final savedDevices = await SpUtil.getList(_storageKey) ?? [];
      print('🔍 Initializing cached devices: ${savedDevices.length}');
      for (var deviceData in savedDevices) {
        print('🔍 Initializing cached device: ${deviceData}');
        deviceInfoMap[deviceData['id']] = DeviceCachedInfo.fromJson(deviceData);
      }
      deviceInfoMap['EE2FFCCE-A094-8369-0B33-71D2C11D995B']!.canCast = true;
      deviceInfoMap.refresh();
      print('✅ Initialized cached devices: ${deviceInfoMap.length}');
    } catch (e) {
      print('Error loading devices: $e');
    }
  }

  // 移除设备
  Future<void> removeDevice(String id) async {
    // Remove device info from cache
    deviceInfoMap.remove(id);
    deviceInfoMap.refresh();
    await saveDevicesToStorage();
    ToastUtils.showSuccess('解绑成功');
  }

  // 保存设备到存储
  Future<void> saveDevicesToStorage() async {
    try {
      final devicesList =
          deviceInfoMap.values.map((info) => info.toJson()).toList();
      await SpUtil.setList(_storageKey, devicesList);
      deviceInfoMap.refresh();
    } catch (e) {
      print('Error saving devices: $e');
    }
  }

  // 选择设备
  void selectDevice(List<DeviceCachedInfo> devices, String source) async {
    if (!devices.any((d) => d.canCast)) {
      ToastUtils.showError('设备不存在');
      return;
    }

    if (source == 'picker') {
      // If called from picker, return to previous screen
      final castController = Get.find<CastController>();

      if (castController.templateModelA.value != null) {
        final size =
            castController.templateModelA.value!.size.split('|')[1].split('X');
        if (devices.any((d) =>
            d.displayInfo.isEmpty ||
            (d.displayInfo[0].width != int.parse(size[0].trim()) ||
                d.displayInfo[0].height != int.parse(size[1].trim())))) {
          ToastUtils.showError('设备分辨率不匹配');
          return;
        }
      }
      if (castController.templateModelB.value != null) {
        final size =
            castController.templateModelB.value!.size.split('|')[1].split('X');
        if (devices.any((d) =>
            d.displayInfo.isEmpty ||
            (d.displayInfo[0].width != int.parse(size[0].trim()) ||
                d.displayInfo[0].height != int.parse(size[1].trim())))) {
          ToastUtils.showError('设备分辨率不匹配');
          return;
        }
      }
      Get.back(result: devices);
    } else {
      // If called from tab, switch to cast tab and pass device data
      final homeController = Get.find<HomeController>();
      final castController = Get.find<CastController>();

      // Add device to selected devices if not already present

      if (castController.validateDeviceResolution(devices))
        // Switch to cast tab (index 0)
        homeController.changeIndex(0);
    }
  }

  // 1、 点开设备管理界面时，设备从数据库里直接读取，显示列表即可，设备的信息是添加完读取一次保存到数据库就可以，不会改变，唯一会变化需要更新的是电池电量。
// 2、 点开管理界面时，启动蓝牙扫描，即可同时更新设备列表的设备在线状态，有收到对应mac地址的设备，标记为在线，超过5秒都扫描不到的设备 标为离线。可在扫描到的设备里记录下最后一次收到广播消息的时间戳，每个扫描周期结束更新离线状态。
// 流程为：用户点开设备界面时：
// 1、 首先从数据库读取所有设备，显示刷新设备列表
// 2、 后台启动蓝牙扫描（扫描5秒结束），在收到蓝牙扫描到的mac地址，去列表里更新设备离线状态，过滤掉信号低于-90db的设备（信号太差会影响后面传输稳定性体验不好）。
// 3、 扫描结束后，检查是否有需要更新电池电量的设备，如果有，开始读取电量，链接不上的设备，标记为离线，读取成功记录电池电量和时间戳到数据库。
// 4、 检查是否有添加的设备没有完整的设备属性信息，比如屏幕分辨率类型等等，缺少的去读取并添加到数据库。
// 5、 超过3天没有更新电量的，读取更新电池电量。保存到数据库
// 6、 循环2-5步骤
// 下拉强制刷新时，重复以上步骤即可
  Future<void> checkPermissionAndStartScan() async {
    print('🔍 checkPermissionAndStartScan');
    // 检查设备是否支持蓝牙
    if (await FlutterBluePlus.isSupported == false) {
      ToastUtils.showError('设备不支持蓝牙');
      return;
    }

    if (FlutterBluePlus.isScanningNow) {
      // ToastUtils.show('正在扫描...');
      print('🔍 正在扫描...,忽略此次扫描');
      return;
    }

    var bluetoothStatus = await Permission.bluetooth.status;

    if (!bluetoothStatus.isGranted) {
      await Permission.bluetooth.request();
    }

    if (Platform.isAndroid) {
      var locationStatus = await Permission.location.status;

      if (!locationStatus.isGranted) {
        await Permission.location.request();
      }
      if (!locationStatus.isGranted) {
        ToastUtils.showError('请打开位置权限');
        return;
      }

      await Permission.ignoreBatteryOptimizations.request();
    }

    // 先获取当前蓝牙状态
    final currentState = await FlutterBluePlus.adapterState.first;
    if (currentState == BluetoothAdapterState.on) {
      // 如果蓝牙已经开启，直接开始扫描
      await startScan();
      return;
    }

    // 如果蓝牙未开启，监听状态变化
    StreamSubscription? stateSubscription;
    stateSubscription = FlutterBluePlus.adapterState.listen((state) async {
      print('蓝牙状态: $state');
      if (state == BluetoothAdapterState.on) {
        // 取消监听后再开始扫描
        await stateSubscription?.cancel();
        await startScan();
      } else if (state == BluetoothAdapterState.off) {
        if (Platform.isAndroid) {
          try {
            await FlutterBluePlus.turnOn();
          } catch (e) {
            print('开启蓝牙失败: $e');
            ToastUtils.showError('请手动开启蓝牙');
          }
        } else {
          ToastUtils.showError('请开启蓝牙');
        }
      }
    });
  }

  Future<void> startScan(
      {Duration timeout = const Duration(seconds: 5)}) async {
    print('🔍 Starting BLE scan...');

    if (FlutterBluePlus.isScanningNow) {
      print('⚠️ Scan already in progress');
      return;
    }

    scanResults.clear();

    StreamSubscription? scanSubscription;
    StreamSubscription? stateSubscription;

    try {
      await FlutterBluePlus.stopScan();
      await Future.delayed(const Duration(milliseconds: 100));

      // 扫描结果监听
      scanSubscription = FlutterBluePlus.scanResults.listen(
        (results) {
          for (final r in results) {
            if (!scanResults.contains(r)) {
              print(
                  '📱 Found device: ${r.device.platformName} (${r.device.remoteId})');
              scanResults.add(r);
            }

            // 更新已连接设备列表
            if (!connectedDevices
                .any((d) => d.id == r.device.remoteId.toString())) {
              final device = r.device;
              connectedDevices.add(DeviceCachedInfo(
                id: device.remoteId.toString(),
                name: device.platformName,
                lastConnected: DateTime.now(),
                group: AppLocalizations.of(Get.context!)!
                    .translate('device_default_group'),
                groupId: '0',
                displayInfo: [],
                batteryLevel: null,
                firmwareVersion: '--',
                connectedTime: DateTime.now(),
                rssi: r.rssi,
              ));
            } else {
              final index = connectedDevices
                  .indexWhere((d) => d.id == r.device.remoteId.toString());
              connectedDevices[index] = connectedDevices[index].copyWith(
                lastConnected: DateTime.now(),
                rssi: r.rssi,
              );
            }
          }
        },
        onError: (e) => print('❌ Scan result error: $e'),
      );

      FlutterBluePlus.cancelWhenScanComplete(scanSubscription);

      await FlutterBluePlus.startScan(
        timeout: timeout,
        withNames: ['BOMALINK_ESL'],
      );

      stateSubscription = FlutterBluePlus.isScanning.listen(
        (scanning) async {
          print(scanning ? '🔍 Scanning...' : '✋ Scan stopped');

          if (!scanning) {
            scanSubscription?.cancel();
            stateSubscription?.cancel();

            if (scanResults.isNotEmpty) {
              // 处理扫描结果
              for (var e in deviceInfoMap.values) {
                // 查找对应的扫描结果
                var matchingResults = scanResults.where(
                    (result) => result.device.remoteId.toString() == e.id);

                // 检查是否找到设备且信号强度满足要求
                for (var result in matchingResults) {
                  print('📱 Device ${e.id} RSSI: ${result.rssi}dB');

                  // 只有当信号强度大于-90dB时才标记为在线
                  if (result.rssi > -90) {
                    e.canCast = true;
                    e.rssi = result.rssi;
                    print(
                        '✅ Device ${e.id} is online with RSSI: ${result.rssi}dB');
                  } else {
                    e.canCast = false;
                    e.rssi = result.rssi;
                    print(
                        '⚠️ Device ${e.id} signal too weak: ${result.rssi}dB');
                  }
                }
              }
              deviceInfoMap.refresh();
              await saveDevicesToStorage();
              await connectLocalCachedDevices();
            } else {
              print('⚠️ No devices found');
            }
          }
        },
        onError: (e) => print('❌ Scan state error: $e'),
      );
    } catch (e) {
      print('❌ Scan failed: $e');
      ToastUtils.showError(
          AppLocalizations.of(Get.context!)!.translate('device_scan_failed'));
    } finally {}
  }

  Future<void> stopScan() async {
    try {
      await FlutterBluePlus.stopScan();
      print('✋ Scan stopped');
    } catch (e) {
      print('⚠️ Error stopping scan: $e');
    }
  }

  Future<void> connectLocalCachedDevices({bool isRefresh = false}) async {
    List<BluetoothDevice> devices = [];
    final now = DateTime.now();

    for (var e in deviceInfoMap.values) {
      try {
        // 计算时间差（分钟）
        final timeDifference = now.difference(e.lastConnected).inDays;
        print(
            '🔍 Device ${e.id} last connected ${timeDifference} days ago');

        // 如果设备最后连接时间超过3分钟，或者是强制刷新
        if (timeDifference > 3 || isRefresh) {
          final device = BluetoothDevice.fromId(e.id);
          devices.add(device);
        }
      } catch (e) {
        print('❌ Error connecting local cached devices: $e');
      }
    }

    print('🔍 Found ${devices.length} devices needing connection update');
    return processBatchConnections(devices);
  }

  Future<void> processBatchConnections(List<BluetoothDevice> devices) async {
    final int batchSize = MAX_CONCURRENT_CONNECTIONS;
    final int totalDevices = devices.length;
    int processedCount = 0;

    while (processedCount < totalDevices) {
      // 检查是否取消
      if (isCancelling.value) {
        print('🛑 Connection process cancelled');
        return;
      }

      final currentBatch =
          devices.skip(processedCount).take(batchSize).toList();
      print(
          '📱 Processing batch: ${processedCount + 1} to ${processedCount + currentBatch.length} of $totalDevices');

      try {
        await connectToDevices(currentBatch);

        // 断开连接但保持设备信息
        for (var device in currentBatch) {
          try {
            // await device.disconnect();
            // 不从 connectedDevices 中移除，只更新连接状态
            final index = connectedDevices
                .indexWhere((d) => d.id == device.remoteId.toString());
            if (index != -1) {
              connectedDevices[index] = connectedDevices[index].copyWith(
                lastConnected: DateTime.now(),
              );
            }
          } catch (e) {
            print('⚠️ Error disconnecting device ${device.remoteId}: $e');
          }
        }
      } catch (e) {
        print('❌ Error processing batch: $e');
      }

      processedCount += currentBatch.length;

      if (processedCount < totalDevices) {
        await Future.delayed(const Duration(milliseconds: 500));
      }
    }

    print('✅ Completed processing all ${devices.length} devices');
    return Future.value();
  }

  Future<void> connectToDevices(List<BluetoothDevice> devices) async {
    if (isConnecting.value) {
      print('⏳ Connection in progress, adding to queue');
      connectionQueue.addAll(devices);
      return;
    }

    isConnecting.value = true;
    try {
      for (final device in devices) {
        // 检查是否取消
        if (isCancelling.value) {
          print('🛑 Connection cancelled for device: ${device.remoteId}');
          break;
        }

        try {
          print('🔄 Connecting to device: ${device.remoteId}');
          await device.connect(timeout: CONNECT_TIMEOUT);

          print('📖 Reading device info for: ${device.remoteId}');
          final deviceInfo = await readDisplayInfo(device);
          deviceInfo.rssi = await device.readRssi();

          // 更新或添加设备信息到缓存
          if (deviceInfoMap.containsKey(device.remoteId.toString())) {
            deviceInfoMap[device.remoteId.toString()] =
                deviceInfoMap[device.remoteId.toString()]!.copyWith(
                    canCast: true,
                    displayInfo: deviceInfo.displayInfo,
                    batteryLevel: deviceInfo.batteryLevel,
                    firmwareVersion: deviceInfo.firmwareVersion,
                    board: deviceInfo.board,
                    lastConnected: DateTime.now(),
                    connectedTime: deviceInfo.connectedTime,
                    rssi: deviceInfo.rssi);
            deviceInfoMap.refresh();

            final selectedDevice = Get.find<CastController>()
                .selectedDevices
                .firstWhereOrNull((e) => e.id == device.remoteId.toString());
            if (selectedDevice != null) {
              final castController = Get.find<CastController>();
              final index = castController.selectedDevices
                  .indexWhere((d) => d.id == device.remoteId.toString());
              if (index != -1) {
                castController.selectedDevices[index] =
                    deviceInfoMap[device.remoteId.toString()]!;
                castController.selectedDevices.refresh();
              }
            }
          }
          // 更新已连接设备列表
          if (!connectedDevices.any((d) => d.id == deviceInfo.id)) {
            connectedDevices.add(deviceInfo);
          } else {
            final index =
                connectedDevices.indexWhere((d) => d.id == deviceInfo.id);
            connectedDevices[index] = deviceInfo;
          }

          if (!nfcScanResults.any((d) => d.id == deviceInfo.id)) {
            nfcScanResults.add(deviceInfo);
          } else {
            final index =
                nfcScanResults.indexWhere((d) => d.id == deviceInfo.id);
            nfcScanResults[index] = deviceInfo;
          }
          await device.disconnect();
          print('✅ Successfully processed device: ${device.remoteId}');
        } catch (e) {
          print('❌ Failed to process device ${device.remoteId}: $e');
          // 从已连接设备列表中移除失败的设备
          connectedDevices
              .removeWhere((d) => d.id == device.remoteId.toString());
        }
      }
    } finally {
      print('🏁 Connection process completed');
      isConnecting.value = false;
      await saveDevicesToStorage(); // 保存更新后的设备信息
    }
  }

  Future<void> disconnectDevice(String deviceId) async {
    try {
      print('📤 Disconnecting device: ${deviceId}');
      final device = FlutterBluePlus.connectedDevices
          .firstWhere((d) => d.remoteId.toString() == deviceId);
      await device.disconnect();
      connectedDevices.removeWhere((d) => d.id == deviceId);
      connectionProgress.remove(deviceId);
      print('✅ Successfully disconnected device: ${deviceId}');
    } catch (e) {
      print('❌ Error disconnecting device ${deviceId}: $e');
      rethrow;
    }
  }

  Future<void> disconnectAllDevices() async {
    for (var device in connectedDevices.toList()) {
      await disconnectDevice(device.id);
    }
    connectedDevices.clear();
    connectionProgress.clear();
  }

  Future<DeviceCachedInfo> readDisplayInfo(BluetoothDevice device) async {
    print('📱 开始读取设备信息: ${device.remoteId}');
    final List<Map<String, dynamic>> servicesInfo = [];
    final List<EslDisplayInfo> localDisplayInfo = [];
    int? localBatteryLevel;
    String localFirmwareVersion = '';
    String localBoard = '';

    try {
      print('🔍 正在发现服务...');
      final services = await device.discoverServices();
      print('✅ 发现 ${services.length} 个服务');

      // Read ESL display info
      try {
        print('🔍 查找 ESL 服务 (1857)...');
        final eslService = services.firstWhere(
          (service) => service.uuid.toString().toUpperCase().contains("1857"),
        );
        print('✅ 找到 ESL 服务: ${eslService.uuid}');

        print('🔍 查找显示信息特征值 (2BFA)...');
        final displayInfoChar = eslService.characteristics.firstWhere(
          (char) => char.uuid.toString().toUpperCase().contains("2BFA"),
        );
        print('✅ 找到显示信息特征值: ${displayInfoChar.uuid}');

        if (Platform.isIOS) {
          print('⏳ iOS设备，添加200ms延迟...');
          await Future.delayed(const Duration(milliseconds: 200));
        }

        print('📖 读取显示信息数据...');
        final data = await displayInfoChar.read();
        print(
            '📊 原始数据: ${data.map((e) => e.toRadixString(16).padLeft(2, '0')).join(':')}');

        if (data.length >= 5) {
          if (Platform.isIOS) {
            print('🍎 解析 iOS 显示信息...');
            localDisplayInfo.add(EslDisplayInfo.fromBytes(data.sublist(0, 5)));
            print(
                '📱 显示屏1: ${localDisplayInfo[0].width}x${localDisplayInfo[0].height}');

            if (data.length >= 10) {
              localDisplayInfo
                  .add(EslDisplayInfo.fromBytes(data.sublist(5, 10)));
              print(
                  '📱 显示屏2: ${localDisplayInfo[1].width}x${localDisplayInfo[1].height}');
            }
          } else {
            print('🤖 解析 Android 显示信息...');
            for (var i = 0;
                i < data.length && localDisplayInfo.length < 2;
                i += 5) {
              if (i + 5 <= data.length) {
                final display =
                    EslDisplayInfo.fromBytes(data.sublist(i, i + 5));
                localDisplayInfo.add(display);
                print(
                    '📱 显示屏${localDisplayInfo.length}: ${display.width}x${display.height}');
              }
            }
          }
          print('✅ 成功解析 ${localDisplayInfo.length} 个显示屏信息');
        }
      } catch (e) {
        print('❌ 读取显示信息失败: $e');
      }

      // Read battery info
      try {
        print('🔍 查找电池服务 (180F)...');
        final batteryService = services.firstWhere(
          (service) => service.uuid.toString().toUpperCase().contains("180F"),
        );
        print('✅ 找到电池服务');

        print('🔍 查找电池特征值 (2A19)...');
        final batteryChar = batteryService.characteristics.firstWhere(
          (char) => char.uuid.toString().toUpperCase().contains("2A19"),
        );
        print('✅ 找到电池特征值');

        print('📖 读取电池数据...');
        final batteryData = await batteryChar.read();
        localBatteryLevel = batteryData[0];
        print('🔋 电池电量: $localBatteryLevel%');
      } catch (e) {
        print('❌ 读取电池信息失败: $e');
      }

      // Read firmware version
      try {
        print('🔍 查找设备信息服务 (180A)...');
        final deviceInfoService = services.firstWhere(
          (service) => service.uuid.toString().toUpperCase().contains("180A"),
        );
        print('✅ 找到设备信息服务');

        print('🔍 查找固件版本特征值 (2A26)...');
        final firmwareChar = deviceInfoService.characteristics.firstWhere(
          (char) => char.uuid.toString().toUpperCase().contains("2A26"),
        );
        print('✅ 找到固件版本特征值');

        print('📖 读取固件版本...');
        final versionData = await firmwareChar.read();
        localFirmwareVersion = String.fromCharCodes(versionData).trim();
        print('📱 固件版本: $localFirmwareVersion');

        print('🔍 查找主板信息特征值 (2A24)...');
        final boardChar = deviceInfoService.characteristics.firstWhere(
          (char) => char.uuid.toString().toUpperCase().contains("2A24"),
        );
        print('✅ 找到主板信息特征值');

        print('📖 读取主板信息...');
        final boardData = await boardChar.read();
        localBoard = String.fromCharCodes(boardData).trim();
        print('📱 主板型号: $localBoard');
      } catch (e) {
        print('❌ 读取固件信息失败: $e');
      }

      print('✅ 设备信息读取完成');
      return DeviceCachedInfo(
        id: device.remoteId.toString(),
        name: device.platformName,
        lastConnected: DateTime.now(),
        group: '',
        displayInfo: localDisplayInfo,
        board: localBoard,
        batteryLevel: localBatteryLevel,
        firmwareVersion: localFirmwareVersion,
        connectedTime: DateTime.now(),
      );
    } catch (e) {
      print('❌ 设备信息读取失败: $e');
      rethrow;
    }
  }

  String _getCharacteristicProperties(BluetoothCharacteristic char) {
    final props = <String>[];
    if (char.properties.broadcast) props.add('Broadcast');
    if (char.properties.read) props.add('Read');
    if (char.properties.writeWithoutResponse) props.add('WriteWithoutResponse');
    if (char.properties.write) props.add('Write');
    if (char.properties.notify) props.add('Notify');
    if (char.properties.indicate) props.add('Indicate');
    if (char.properties.authenticatedSignedWrites)
      props.add('AuthenticatedSignedWrites');
    if (char.properties.extendedProperties) props.add('ExtendedProperties');
    return props.join(', ');
  }

  String _getServiceName(String uuid) {
    final serviceUuids = {
      '1800': 'Generic Access',
      '1801': 'Generic Attribute',
      '180a': 'Device Information',
      '180f': 'Battery Service',
      '1812': 'Human Interface Device',
      '1826': 'Fitness Machine',
    };

    return serviceUuids[uuid.toLowerCase()] ?? 'Unknown Service';
  }

  // Add NFC availability check
  final isNfcAvailable = false.obs;

  // Initialize NFC
  Future<void> initNfc() async {
    try {
      nfcScanResults.clear();
      isNfcAvailable.value = await NfcManager.instance.isAvailable();
      if (isNfcAvailable.value) {
        print('✅ NFC is available');
        await _startNfcSession();
      } else {
        print('⚠️ NFC is not available');
      }
    } catch (e) {
      print('❌ Error initializing NFC: $e');
    }
    return Future.value();
  }

  Future<void> _startNfcSession() async {
    print('🔍 _startNfcSession');
    NfcManager.instance.startSession(
      onDiscovered: (NfcTag tag) async {
        try {
          print('🔍 onDiscovered');
          final ndefTag = Ndef.from(tag);
          if (ndefTag == null) {
            ToastUtils.showError('不支持的NFC标签格式');
            return Future.value();
          }

          final message = ndefTag.cachedMessage;
          if (message == null) {
            ToastUtils.showError('NFC标签为空');
            return Future.value();
          }
          print('🔍 NFC message: ${message.records.toString()}');
          final deviceInfo = _parseNfcDeviceInfo(message);
          if (deviceInfo != null) {
            nfcScanResults.add(deviceInfo);
          }
          return Future.value();
        } catch (e) {
          print('❌ Error reading NFC tag: $e');
          ToastUtils.showError('读取NFC标签失败');
          return Future.value();
        } finally {
          await NfcManager.instance.stopSession();
        }
      },
      onError: (error) {
        print('❌ NFC session error: $error');
        ToastUtils.showError('NFC连接失败');
        return Future.value();
      },
    );
  }

  DeviceCachedInfo? _parseNfcDeviceInfo(NdefMessage message) {
    try {
      final records = message.records;
      print('📝 Found ${records.length} NDEF records');

      String? macAddress;
      int displayNumber = 1;
      int displayType = 0;
      String resolution = '';
      int imageMax = 0;

      // Parse each record
      for (final record in records) {
        if (record.typeNameFormat == NdefTypeNameFormat.nfcWellknown) {
          final languageCodeLength = record.payload[0];
          final textContent = String.fromCharCodes(
                  record.payload.sublist(1 + languageCodeLength))
              .trim();

          print('Record content: $textContent');

          // Parse MAC address
          if (textContent.contains('MAC:')) {
            macAddress = textContent
                .split('MAC:')[1]
                .trim()
                .replaceAll("\"", "")
                .replaceAll(RegExp(r'[\n\r\s\x00]'), '');
          }
          // Parse display number
          else if (textContent.startsWith('display_number:')) {
            final splitResult = textContent
                .split('display_number:')[1]
                .trim()
                .replaceAll("\"", "")
                .replaceAll(RegExp(r'[\n\r\s\x00]'), '');
            print('Split result: "$splitResult"');
            print('Split result bytes: ${splitResult.codeUnits}');
            displayNumber = int.tryParse(splitResult) ?? 1;
            print(
                'Parsed displayNumber: $displayNumber from "$splitResult"');
          }
          // Parse display type
          else if (textContent.startsWith('display_type:')) {
            displayType = int.tryParse(textContent.split(':')[1]) ?? 0;
          }
          // Parse resolution
          else if (textContent.startsWith('resolution:')) {
            resolution = textContent.split(':')[1];
          }
          // Parse image max
          else if (textContent.startsWith('image_max:')) {
            imageMax = int.tryParse(textContent.split(':')[1]) ?? 0;
          }
        }
      }

      print('displayNumber: $displayNumber');

      // Create display info based on parsed data
      if (macAddress != null && resolution.isNotEmpty) {
        final resolutionParts = resolution.split('x');
        if (resolutionParts.length == 2) {
          final width = int.tryParse(resolutionParts[0]) ?? 0;
          final height = int.tryParse(resolutionParts[1]) ?? 0;

          return DeviceCachedInfo(
            id: macAddress,
            name: 'BOMALINK_ESL',
            lastConnected: DateTime.now(),
            group: AppLocalizations.of(Get.context!)!
                .translate('device_default_group'),
            groupId: '0',
            canCast: true,
            displayInfo: [
              for (var i = 0; i < displayNumber; i++)
                EslDisplayInfo(
                  displayType: displayType,
                  width: width,
                  height: height,
                )
            ],
            board: '',
            batteryLevel: null,
            firmwareVersion: '--',
            connectedTime: DateTime.now(),
          );
        }
      }

      print('❌ Invalid or incomplete NFC data');
      return null;
    } catch (e) {
      print('❌ Error parsing NFC data: $e');
      return null;
    }
  }

  // 添加写入 NFC 标签的方法
  Future<void> writeNfcTag(String deviceId, String deviceName) async {
    try {
      if (!isNfcAvailable.value) {
        ToastUtils.showError('设备不支持NFC');
        return;
      }

      await NfcManager.instance.startSession(
        onDiscovered: (NfcTag tag) async {
          try {
            final ndef = Ndef.from(tag);
            if (ndef == null) {
              ToastUtils.showError('不支持的NFC标签格式');
              return;
            }

            final message = NdefMessage([
              // 设备ID记录
              NdefRecord.createText(deviceId),
              // 设备名称记录
              NdefRecord.createText(deviceName),
            ]);

            await ndef.write(message);
            ToastUtils.showSuccess('NFC标签写入成功');
          } catch (e) {
            print('❌ Error writing NFC tag: $e');
            ToastUtils.showError('写入NFC标签失败');
          } finally {
            await NfcManager.instance.stopSession();
          }
        },
      );
    } catch (e) {
      print('❌ Error starting NFC session: $e');
      ToastUtils.showError('NFC操作失败');
    }
  }

  stopSession() {
    NfcManager.instance.stopSession();
  }

  Future<BluetoothDevice?> scanForDevice(String targetId,
      {Duration? timeout}) async {
    print('🔍 [scanForDevice] Starting scan for device ID: $targetId');
    print('📱 [scanForDevice] Current adapter state: ${await FlutterBluePlus.adapterState.first}');

    try {
      if (FlutterBluePlus.isScanningNow) {
        print('⏸ [scanForDevice] Stopping existing scan...');
        await stopScan();
        await Future.delayed(const Duration(milliseconds: 100));
      }

      if (Platform.isAndroid) {
        final state = await FlutterBluePlus.adapterState.first;
        print('📱 [scanForDevice] Android BT state: $state');
        if (state == BluetoothAdapterState.off) {
          print('🔄 [scanForDevice] Turning on Bluetooth...');
          await FlutterBluePlus.turnOn();
        }
      }

      scanResults.clear();
      print('🧹 [scanForDevice] Cleared previous scan results');

      final completer = Completer<BluetoothDevice?>();
      StreamSubscription? scanSubscription;

      scanSubscription = FlutterBluePlus.scanResults.listen(
        (results) {
          print('📡 [scanForDevice] Scan found ${results.length} devices');
          for (final r in results) {
            print('📱 [scanForDevice] Device: ${r.device.platformName} (${r.device.remoteId}) RSSI: ${r.rssi}');
            if (r.device.remoteId.toString().toUpperCase() == targetId.toUpperCase()) {
              print('✅ [scanForDevice] Target device found with RSSI: ${r.rssi}');
              scanSubscription?.cancel();
              FlutterBluePlus.stopScan();
              if (!completer.isCompleted) completer.complete(r.device);
              return;
            }
          }
        },
        onError: (e) {
          print('❌ [scanForDevice] Scan error: $e');
          if (!completer.isCompleted) completer.complete(null);
        }
      );

      print('🔍 [scanForDevice] Starting scan with timeout: ${timeout?.inSeconds ?? 10}s');
      await FlutterBluePlus.startScan(
        timeout: timeout ?? const Duration(seconds: 10),
        withNames: ['BOMALINK_ESL'],
      );

      return await completer.future;
    } catch (e) {
      print('❌ [scanForDevice] Scan failed with error: $e');
      return null;
    }
  }

  // 添加取消连接标志
  final isCancelling = false.obs;

  // 取消连接方法
  Future<void> cancelConnections() async {
    print('🛑 Cancelling all connections...');
    isCancelling.value = true;

    // 清空连接队列
    connectionQueue.clear();

    // 断开所有正在连接的设备
    final connectedDevices = await FlutterBluePlus.connectedDevices;
    for (final device in connectedDevices) {
      try {
        print('Disconnecting device: ${device.remoteId}');
        await device.disconnect();
        await Future.delayed(const Duration(milliseconds: 300));
      } catch (e) {
        print('Error disconnecting device ${device.remoteId}: $e');
      }
    }

    // 停止扫描
    await stopScan();

    // 重置状态
    isConnecting.value = false;
    isCancelling.value = false;

    print('✅ All connections cancelled');
  }
}
